import {XiaohongshuModel} from "../../model/XiaohongshuModel";
import {Op} from "sequelize";
import fetch from "node-fetch";
import {flatMap, groupBy, head, includes, isEmpty, isNil, keyBy, map, replace} from "lodash";
import {FansResultModel} from "../../model/FansResultModel";
import {writeExcel} from "../../excel/excel";
import {SheetModel} from "../../model/SheetModel";
import {FansResultCityModel} from "../../model/FansResultCityModel";

const limit =5;
let usertoken ='';
const setCookie =async (value:string)=>{
    usertoken = value;
    await global.redis.set('usertoken',value);
    //fs.writeFileSync('usercookie.txt',value);
}
const removeCookie =async ()=>{
    usertoken ='';
    //if (fs.existsSync('usercookie.txt'))
   // fs.unlinkSync('usercookie.txt');
    await global.redis.remove('usertoken');
};
const getCookie =async ()=>{
    if (!isEmpty(usertoken)){
        return usertoken;
    }
    // if (!fs.existsSync('usercookie.txt')){
    //     usertoken ='';
    //     return '';
    // }
   return  await global.redis.get('usertoken');
    // return fs.readFileSync('usercookie.txt','utf-8');
};
const getHeaders =async (ispost?:boolean)=>{
    const cookie = await getCookie();
    const token =cookie;
    const header =  {
        "accept": "application/json, text/plain, */*",
        "accept-language": "zh-CN,zh;q=0.9",
        "sec-ch-ua": "\"Chromium\";v=\"119\", \"Not?A_Brand\";v=\"24\"",
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": "\"Windows\"",
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors",
        "sec-fetch-site": "same-site",
        "cookie": "Hm_lvt_c6d9cdbaf0b464645ff2ee32a71ea1ae=1704159740; ASP.NET_SessionId=iscujlruhlr5sfuyyiz24sao; Hm_lpvt_c6d9cdbaf0b464645ff2ee32a71ea1ae=1704182113; "+token,
        "Referer": "https://app.qian-gua.com/",
        "Referrer-Policy": "no-referrer-when-downgrade"
    };
    if(ispost == true){
        header['content-type'] = "application/json;charset=UTF-8";
    }
    return  header;
};
export const login =async ()=>{
   const response =  await fetch("https://api.qian-gua.com/Login/Login", {
        "headers": {
            "accept": "*/*",
            "accept-language": "zh-CN,zh;q=0.9",
            "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
            "sec-ch-ua": "\"Chromium\";v=\"119\", \"Not?A_Brand\";v=\"24\"",
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": "\"Windows\"",
            "sec-fetch-dest": "empty",
            "sec-fetch-mode": "cors",
            "sec-fetch-site": "same-site",
            "cookie": "Hm_lvt_c6d9cdbaf0b464645ff2ee32a71ea1ae=1704159740; ASP.NET_SessionId=iscujlruhlr5sfuyyiz24sao; Hm_lpvt_c6d9cdbaf0b464645ff2ee32a71ea1ae=1704182113",
            "Referer": "https://www.qian-gua.com/",
            "Referrer-Policy": "no-referrer-when-downgrade"
        },
        "body": "tel=18603539357&pwd=kolrank.com",
        "method": "POST"
    });
    console.log('==登陆返回信息====')
    const cookiestr = response.headers.get('set-cookie');
    const usercookie = cookiestr.split(";").filter(item=>item.includes("User=")).toString();
    if (isEmpty(usercookie)){
        console.error("登陆失败")
    }else{
        await setCookie(usercookie);
        console.log("登陆成功")
    }
}
export const fetchXiaohongshu =async ()=>{
      const rows = await SheetModel.findAll({
          where: {
              redId: {
                  [Op.is]: null
              },
              isExistLink: {
                  [Op.eq]: 0
              },
              link:{
                  [Op.not]: null
              }
          },
          limit: limit
      })

    for (const row of rows) {
        const text= await fetch(row.link, {headers: {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'}}).then(res=>res.text())
        const preg = /<script>window.__INITIAL_STATE__=(.*?)<\/script>/
        const arr = text.match(preg);
        console.log(!isNil( arr))
        if (!isNil( arr)){
            const str = arr[1].replace(new RegExp('undefined',"gm"), '1000000')
            const json = JSON.parse(str);
            const {redId,nickname} = json['user']['userPageData']['basicInfo'];
            await SheetModel.update({redId, nickname}, {where: {id: row.id}});
        }else{
            await SheetModel.update({isExistLink:1}, {where: {id: row.id}});
            console.info(arr)
            console.warn("获取小红书页面出错,再重试")
        }
    }
}

export const buildXhsUserLinkQiangua =async ()=>{

    const rows = await XiaohongshuModel.findAll({
        where: {
            BloggerId: {
                [Op.is]: null
            },
            redId: {
                [Op.not]: null
            },
            isException:{
                [Op.eq]:0
            }
        },
        limit:limit
    })

    let islogin = false;
    for (const row of rows) {
        console.log(row.redId)
        try {
             const Data = await redIdlinkbloggerId(row.redId);
            if (Data==401 ){
                islogin = true;
                break;
            }

            if (Data['BloggerTotal']==0){
                await XiaohongshuModel.update({isException:1}, {where: {id: row.id}});
            }
            //console.log(Data)
            if ( Data['BloggerItemList'].length>0 ){
                const item = head(Data['BloggerItemList']);
                await XiaohongshuModel.update({BloggerId:item['BloggerId'],BloggerIdKey:item['BloggerIdKey']}, {where: {id: row.id}});
            }
        }catch (e){
            console.error(e)
        }
    }
}
export const buildSheetUserLinkQiangua =async ()=>{
    const rows = await SheetModel.findAll({
        where: {
            BloggerId: {
                [Op.is]: null
            },
            redId: {
                [Op.not]: null
            },
            isException:{
                [Op.eq]:0
            }
        },
        limit:limit
    })
    let islogin = false;
    for (const row of rows) {
        console.log(row.redId)
        try {
            const Data = await redIdlinkbloggerId(row.redId);
            if (Data==401 ){
                islogin = true;
                break;
            }
            if (Data['BloggerTotal']==0){
                await SheetModel.update({isException:1}, {where: {id: row.id}});
            }
            //console.log(Data)
            const item = head(Data['BloggerItemList']);
            await SheetModel.update({BloggerId:item['BloggerId'],BloggerIdKey:item['BloggerIdKey']}, {where: {id: row.id}});
        }catch (e){
            console.error(e)
        }
    }
}
export const runBloggerData = async ()=>{
    const rows = await XiaohongshuModel.findAll({
        where: {
            BloggerId: {
                [Op.not]: null
            },
            isFetchData:{
                [Op.eq]:0
            },
            isException:{
                [Op.eq]:0
            }
        },
        limit:limit
    })
    if (rows.length==0){
        console.log("抓取完毕")
    }
    for (const row of rows) {
        const detail = await GetDetail(row.BloggerId, row.BloggerIdKey);
        const fansinfo = await GetFansInfo(row.BloggerId, row.BloggerIdKey);
        const node = await GetBloggerRangeDataStat(row.BloggerId, row.BloggerIdKey);
        //detail==401 ||
        if ( fansinfo==401 || node==401){
            break;
        }
        await XiaohongshuModel.update({isFetchData: 1}, {where: {id: row.id}});
        console.log(row.redId)
        const res = await FansResultModel.findOne({where: {xhsId: row.id}})
        if (!res){
            await FansResultModel.create({
                xhsId: row.id,
                fansInfo: detail,
                fensDetail: fansinfo,
                noteAnalysis: node,
            })
        }else{
            await FansResultModel.update({
                fansInfo: detail,
                fensDetail: fansinfo,
                noteAnalysis: node,
            }, {where: {xhsId: row.id}})
        }
    }
}

export const runSheetBloggerData = async ()=>{
    const rows = await SheetModel.findAll({
        where: {
            BloggerId: {
                [Op.not]: null
            },
            isFetchData:{
                [Op.eq]:0
            },
            isException:{
                [Op.eq]:0
            }
        },
        limit:limit
    })

    for (const row of rows) {
        const detail = await GetDetail(row.BloggerId, row.BloggerIdKey);
        const fansinfo = await GetFansInfo(row.BloggerId, row.BloggerIdKey);
        const node = await GetBloggerRangeDataStat(row.BloggerId, row.BloggerIdKey);
        //detail==401 ||
        if ( fansinfo==401 || node==401 ||detail == 401){
            break;
        }
        await SheetModel.update({isFetchData: 1}, {where: {id: row.id}});
        console.log(row.redId)
        const res = await FansResultCityModel.findOne({where: {xhsId: row.id}})
        if (!res){
            await FansResultCityModel.create({
                xhsId: row.id,
                fansInfo: detail,
                fensDetail: fansinfo,
                noteAnalysis: node,
            })
        }else{
            await FansResultCityModel.update({
                //fansInfo: detail,
                fensDetail: fansinfo,
                noteAnalysis: node,
            }, {where: {xhsId: row.id}})
        }
    }
}
const redIdlinkbloggerId =async (redId)=>{
    const url = `https://api.qian-gua.com/DataOverView/TotalSearch_Blogger?keyword=${redId}`;
    const json= await fetch(url, {headers: await getHeaders()}).then(res=>res.json())
    const {Code,Data} = json;
    if (Code ==200){
        return Data;
    } else if (Code == 401){
        console.error("登陆超时:",json)
        await commonOp(Code);
        return 401;
    }else{
        console.error("绑定关联用户:",json)
        await XiaohongshuModel.update({isException: 1}, {where: {redId: redId}});
        throw new Error("绑定关联用户失败");
    }
}
 const GetDetail =async (bloggerid:string,sign:string)=>{
    const url = `https://api.qian-gua.com/blogger/GetDetail?bloggerid=${bloggerid}&sign=${sign}`;
    const json= await fetch(url, {headers: await getHeaders()}).then(res=>res.json())
    const {Code,Data} = json;
    if (Code ==200){
        return Data;
    } else if (Code == 401){
        console.error("登陆超时:",json)
        await commonOp(Code);

        return 401;
    }else{
        console.error("获取用户详情失败:",json)
        throw new Error("获取用户详情失败");
    }
}

 const GetFansInfo =async (bloggerid:string,sign:string)=>{
    const url = `https://api.qian-gua.com/blogger/GetFansInfo?bloggerid=${bloggerid}&sign=${sign}`;
    const header = await getHeaders();
    const json= await fetch(url, {headers: header}).then(res=>res.json())
    const {Code,Data} = json;
    if (Code == 200){
        return Data;
    }else if (Code == 401){
        console.error("登陆超时:",json)
        await commonOp(Code);
        return 401;
    }else{
        console.error("获取粉丝信息:",json)
        throw new Error("获取粉丝信息信息失败");
    }
}

 const GetBloggerRangeDataStat =async (bloggerid:string,sign:string)=>{
    const url = `https://api.qian-gua.com/v2/blogger/GetBloggerRangeDataStat`;
    const param = {bloggerid:bloggerid,sign:sign,ishotnote:false,days:30};
     const header = await getHeaders(true);
    const json= await fetch(url, {headers: header,body:JSON.stringify(param),method:'POST'}).then(res=>res.json())
    const {Code,Data} = json;
    if (Code == 200){
        return Data;
    }else if (Code == 401){
        console.error("登陆超时:",json)
        await commonOp(Code);
        return 401;
    }else{
        console.error("获取笔记分析信息:",json)
        throw new Error("获取笔记分析信息失败");
    }
}
const commonOp =async (Code)=>{

    if (Code == 401){
        console.log('重新登陆');
        await removeCookie();
        console.log('清除就的cookie');
        await login();
    }
}
export const exportQueryfans =async ()=>{
    const rows = await FansResultModel.findAll({where:{id:21}});
    const list =[];
    for (const row of rows) {

        const fensDetail = row.fensDetail;
        const note = row.noteAnalysis;
        const maplist ={};
        fensDetail['CityLevel'].forEach(item=>{
            maplist[item['Name']] = (item['Percent']*100).toFixed(2)+"%"
        })

        list.push( Object.assign({
            '昵称':row.fansInfo['NickName'],
            '水粉数':fensDetail['Fans']*fensDetail['FansRobot'],
            '水粉比':fensDetail['FansRobot']+'%',
            '预估阅读中位数':note['ViewCount'],
            '预估点赞中位数':note['LikeCount']
        },maplist) );
    }
    writeExcel('./data.xlsx',list)
}

function formatNumberToTenThousand(number) {
    if (number < 10000) {
        return number.toString(); // 小于万的直接返回原始数字
    } else {
        const tenThousand = number / 10000;
        return tenThousand.toFixed(1) + 'w'; // 大于万的返回以万为单位的字符串
    }
}

export const buildFanData =async ()=>{
    //{where:{xhsId:1}}
    const rows = await FansResultModel.findAll();

    let i =0;
    const list =[];
    for (const row of rows) {

        const fensDetail = row.fensDetail;
        const note = row.noteAnalysis;
        const fans = row.fansInfo;
        console.log(note)

        // fensDetail['CityLevel'].forEach(item=>{
        //     maplist[item['Name']] = (item['Percent']*100).toFixed(2)+"%"
        // })
        let str ="";
        if (fensDetail['Female']>fensDetail['Male']){
            str+="女粉居多 "+fensDetail['Female']+"%,";
        }else{
            str+="男粉居多 "+fensDetail['Male']+"%,";
        }
        if (fensDetail['ProvinceList'].length==0){
            str+="主要地区 0  0% ";
        }else{
            str+="主要地区 "+fensDetail['ProvinceList'][0]['Name']??''+" "+fensDetail['ProvinceList'][0]['Percent']??''+"% ";
        }

        const arr = fensDetail['FansAges'];
        arr.sort((a, b) => b.percent -a.percent  );
        if (arr.length>0){
            str+="主要年龄 "+arr[0]['group']+"岁 "+(arr[0]['percent']*100).toFixed(2)+"% "
        }

        await XiaohongshuModel.update({
            readMedianNum: note['ViewCount'],
            interactMedianNum:note['Lcc'],
            femaleFans:fensDetail['Female']+'%',
            activeFans:fensDetail['FansActive']+'%',
            gouacheFans:fensDetail['FansRobot']+'%',
            estimateVv:note['TotalViewCount'],
            estimateZan:note['TotalLikeCount'],
            fans: fans['VerifyContent']??'',
            attr:str,
            fansNum:formatNumberToTenThousand(fensDetail['Fans']),
            likeNum:formatNumberToTenThousand(note['TotalLikeCount']),
            collectNum: formatNumberToTenThousand(note['TotalCollectCount']),
            noteNum:note['NoteCount'],

        }, {where: {id: row.xhsId}});

        // const res = fensDetail['CityLevel'].filter(item=> includes(['一线城市','新一线城市'],item['Name']));
        // const maps = keyBy(res,'Name');
        // await SheetModel.update({
        //     oneCity: maps['一线城市']?(maps['一线城市']['Percent']*100).toFixed(2)+"%":0,
        //     newOneCity: maps['新一线城市']?(maps['新一线城市']['Percent']*100).toFixed(2)+"%":0,
        // },{where: {id: row.xhsId}})
    }
    console.log('完成')
}

export const buildFanCidyData =async ()=>{
    const rows = await FansResultCityModel.findAll();
// 笔记数  点赞数
    const list =[];
    for (const row of rows) {

        const fensDetail = row.fensDetail;
        const note = row.noteAnalysis;


        // fensDetail['CityLevel'].forEach(item=>{
        //     maplist[item['Name']] = (item['Percent']*100).toFixed(2)+"%"
        // })

        // await XiaohongshuModel.update({
        //     readMedianNum: note['ViewCount'],
        //     interactMedianNum:note['Lcc'],
        //     femaleFans:fensDetail['Female']+'%',
        //     activeFans:fensDetail['FansActive']+'%',
        //     gouacheFans:fensDetail['FansRobot']+'%',
        //     estimateVv:note['TotalViewCount'],
        //     estimateZan:note['TotalLikeCount']
        // }, {where: {id: row.xhsId}});

        const res = fensDetail['CityLevel'].filter(item=> includes(['一线城市','新一线城市'],item['Name']));
        const maps = keyBy(res,'Name');
        await SheetModel.update({
            oneCity: maps['一线城市']?(maps['一线城市']['Percent']*100).toFixed(2)+"%":0,
            newOneCity: maps['新一线城市']?(maps['新一线城市']['Percent']*100).toFixed(2)+"%":0,
            noteNum:note['NoteCount'],
            likeNum:note['TotalLikeCount'],
            collectNum:note['TotalCollectCount'],


        },{where: {id: row.xhsId}})
    }
    console.log('完成')
}
export const runCron= async ()=>{
    // await fetchXiaohongshu();
    //  await buildXhsUserLinkQiangua();
    //await buildSheetUserLinkQiangua();
    await runBloggerData();
   // await runSheetBloggerData();
}
